import { FormInstance, Layout } from 'antd';
import React, { forwardRef, useCallback, useState } from 'react';

import { OperationType } from '../../constant';
import {
  TemplateDetailInfoBE,
  LayerInfoFE,
  RealTimePreviewProps,
  ScreenRefType,
  Info
} from '../../interface';

import TemplateEffect from './components/TemplateEffect';
import TemplateInfo from './components/TemplateInfo';

const { Content } = Layout;

interface EditorProps {
  screenSize: string;
  infoForm: FormInstance<Info>;
  operationType: OperationType;
  templateDetail: Partial<TemplateDetailInfoBE>;
  setScreenSize: (size: string) => void;
  onTemplateDetailChange: (
    templateDetail: Partial<TemplateDetailInfoBE>
  ) => void;
  realTimePreview: (props: RealTimePreviewProps) => Promise<LayerInfoFE[]>;
}

const Editor = forwardRef(
  (props: EditorProps, screenRef: ScreenRefType): JSX.Element => {
    const {
      infoForm,
      screenSize,
      operationType,
      templateDetail,
      setScreenSize,
      realTimePreview,
      onTemplateDetailChange
    } = props;

    const [productImageIndex, setProductImageIndexIndex] = useState(1);

    const handleLayersChange = (feLayers: LayerInfoFE[]): void => {
      onTemplateDetailChange({ ...templateDetail, feLayers });
    };

    const handleRealTimePreview = useCallback(
      async (props: RealTimePreviewProps): Promise<LayerInfoFE[]> => {
        return await realTimePreview({
          ...props
        });
      },
      [realTimePreview]
    );

    return (
      <Content className="p-4 h-full">
        <TemplateInfo
          infoForm={infoForm}
          templateDetail={templateDetail}
          onFormChange={onTemplateDetailChange}
        />
        <TemplateEffect
          /*
           * 这里可能会疑惑为什么已经有templateDetail.feLayers，还需要用 screenRef 拿信息？
           * 可以看到 transferToBELayersInfo 方法中，需要通过当前 screenRef 上的图层的 content 拿 shape 的 base64 图片
           * 因为针对 shape 图层，需要给后端发它的 base 64 图片
           * 这里的逻辑是最后提交之前再去算 shape 的 base 64 图片，因为需要摆正、设置为可见等一系列操作
           * 实时更新可能会耗费一些性能，毕竟这个在前端没啥用🤣
           */
          ref={screenRef} // 画板的Ref。用于切换商品图后刷新 screen 等场景，或者是提交 api 请求的时候获取当前的 layers 信息
          screenSize={screenSize}
          operationType={operationType}
          layers={templateDetail.feLayers} // 当前的 layers 数据
          productImageIndex={productImageIndex} // 当前切换到了哪张 productImage（商品图）
          setScreenSize={setScreenSize}
          onLayersChange={handleLayersChange} // layers 数据改变时候的回调函数（用于同步右侧菜单栏变化）
          realTimePreview={handleRealTimePreview} // text layer 的样式由后端生成，所以属性变化的时候，需要调用接口重新获取图片
          setProductImageIndexIndex={setProductImageIndexIndex} // 修改当前切换到了哪张 productImage（商品图）
        />
      </Content>
    );
  }
);

export default Editor;
